/**
 * Project Reactor
 */


#include "EventLoop.h"

/**
 * EventLoop implementation
 */
// void display(map<int,TcpConnection> &map){
//     for(auto it = map.begin() ; it != map.end() ; it++){
//         cout<<it->first<<":"<<it->second.getSock().getFd()<<endl;
//     }
// }

/**
 * @param accept
 */
EventLoop::EventLoop(Acceptor & acceptor) 
:m_epfd(createEpollFd()),m_acceptor(acceptor)
,m_evtList(MAX_EVTLIST_SIZE),m_isLooping(false)
{
    int listenfd = m_acceptor.getSock().getFd();
    addEpollReadFd(listenfd);
}

EventLoop::~EventLoop() {
    close(m_epfd);
}

void EventLoop::loop() {
    m_isLooping = true;
    while(m_isLooping){
        waitEpollFd();
    }
}

void EventLoop::handleNewConnection() {
    int connfd = m_acceptor.m_accept();
    addEpollReadFd(connfd);

    TcpConnectionPtr con(new TcpConnection(connfd));
    m_connMap[connfd] = con;

    cout<<"建立新连接，连接fd = "<<connfd<<endl;
    cout<<con.get()->streamToString()<<endl;
}

/**
 * @param fd
 */

void EventLoop::handleMessage(int fd) {
    auto it = m_connMap.find(fd); // 获取迭代器
    if (it == m_connMap.end()) {
        cout<<"连接不存在"<<endl;
        return; // 键不存在时直接返回
    }
    bool flag = it->second->isClosed();
    cout<<"连接状态："<<flag<<endl;
    if(flag){
        delEpollReadFd(fd);
        m_connMap.erase(it);
    }else{
        cout<<"本次响应信息："<<it->second->streamToString()<<endl;
        string msg = it->second->receive();
        cout<<"收到消息："<<msg<<endl;
        it->second->send("hello baby\n");
    }

}


/**
 * @return int
 */
int EventLoop::createEpollFd() {
    m_epfd = epoll_create(MAX_EVTLIST_SIZE);
    if(-1 == m_epfd){
        perror("epoll_create");
        return -1;
    }
    return m_epfd;
}

/**
 * @param fd
 */
void EventLoop::addEpollReadFd(int fd) {
    struct epoll_event evt,ep[MAX_EVTLIST_SIZE];
    evt.events = EPOLLIN;
    evt.data.fd = fd;
    int ret = epoll_ctl(m_epfd,EPOLL_CTL_ADD,fd,&evt);
    if(ret<0){
        perror("epoll_ctl");
        return;
    }
    cout<<"添加成功"<<endl;
}

/**
 * @param fd
 */
void EventLoop::delEpollReadFd(int fd) {
    struct epoll_event evt;
    evt.data.fd = fd;
    int ret = epoll_ctl(m_epfd,EPOLL_CTL_DEL,fd,&evt);
    if(ret <0){
        perror("epoll_del");
        return;
    }
}

// int EventLoop::m_epoll_wait() {
//     int readyNum = epoll_wait(m_epfd,m_evtList,MAX_EVTLIST_SIZE,-1);
//     return readyNum;
// }



void EventLoop::unloop() {
    m_isLooping = false;
}

void EventLoop::waitEpollFd() {
    int readyNum = 0;
    do{
        readyNum = epoll_wait(m_epfd,m_evtList.data(),m_evtList.size(),-1);
    }while(-1 == readyNum &&errno == EINTR);
    if(-1 == readyNum){
        std::cerr<<"-1 == readyNum"<<endl;
    }else if(0 == readyNum){
        cout<<"epoll_wait timeout"<<endl;
    }else{
        if(readyNum == (int)m_evtList.size()){
            m_evtList.resize(2*readyNum);
        }
        for(int i = 0 ; i< readyNum ; i++){
            int listenfd = m_acceptor.getSock().getFd();
            if(m_evtList[i].data.fd == listenfd){
                handleNewConnection();
                // display(m_connMap);
            }else{
                int connfd = m_evtList[i].data.fd;
                handleMessage(connfd);
            }
    }
    }
    

}